/* 队列类型的实现 */
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

// 局部函数
static void CopyToNode(Item item, Node * pn);
static void CopyToItem(Node * pn, Item * pi);

/* 初始化队列 */
void InitializeQueue(Queue * pq) {
    pq->front = pq->rear = NULL;   //头尾置为空
    pq->items = 0;       // 项目数量为0
}

/* 判断队列是否已满 true/false */
bool QueueIsFull(const Queue * pq) {
    return pq->items == MAXQUEUE;
}

/* 判断队列是否为空 */
bool QueueIsEmpty(const Queue * pq) {
    return pq->items == 0;
}

/* 返回项目个数 */
int QueueItemCount(const Queue * pq) {
    return pq->items;
}

/* 队列添加项目 */
bool EnQueue(Item item, Queue * pq) {
    Node * pnew;

    if (QueueIsFull(pq))
        return false;
    pnew = (Node *)malloc(sizeof(Node));
    if (pnew == NULL) {
        fprintf(stderr, "Unable to allocate memory!");
        exit(EXIT_FAILURE);
    }
    CopyToNode(item, pnew);   // 把项目复制到新节点上
    pnew->next = NULL;
    if (QueueIsEmpty(pq))
        pq->front = pnew;   // 队列为空，新节点就作为队首
    else
        pq->rear->next = pnew;    // 当前队尾的next指向新节点
    pq->rear = pnew;       // 记录新节点为队尾
    pq->items++;
    return true;
}

/* 队列删除项目 */
bool DeQueue(Item * pitem, Queue * pq) {
    Node * pt;

    if (QueueIsEmpty(pq))
        return false;
    CopyToItem(pq->front, pitem);  // 把队首的项目复制到pitem
    pt = pq->front;
    pq->front = pq->front->next;   // 更新当前队列的头
    free(pt);
    pq->items--;
    if (pq->items == 0)
        pq->rear = NULL;
    return true;
}

/* 清空队列 */
void EmptyTheQueue(Queue * pq) {
    Item dummy;
    while (!QueueIsEmpty(pq))
        DeQueue(&dummy, pq);
}

/* 局部函数 */

static void CopyToNode(Item item, Node * pn) {
    pn->item = item;
}

static void CopyToItem(Node * pn, Item * pi) {
    *pi = pn->item;
}
